package top.whysu.edevice.utils;

import cn.hutool.core.bean.BeanUtil;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 相同字段类之间转换工具类
 */
public class ConverterUtils {
    private static final Logger LOG = LoggerFactory.getLogger(ConverterUtils.class);

    /**
     * @param po
     * @param clazz DTO.class
     * @return : T
     * @Description : 单个 po转dto
     * @Author : youwenfeng
     * @Date : 2018/7/27
     */
    public static <FROM, TO> TO po2dto(FROM po, Class<TO> clazz) {
        return converte(po, clazz);
    }

    /**
     * @param poList
     * @param clazz  DTO.class
     * @return : java.util.List<T>
     * @Description : 批量 po转dto
     * @Author : youwenfeng
     * @Date : 2018/7/27
     */
    public static <FROM, TO> List<TO> po2dto(List<FROM> poList, Class<TO> clazz) {
        return converte(poList, clazz);
    }

    /**
     * @param dto
     * @param clazz PO.class
     * @return : T
     * @Description : 单个 dto转po
     * @Author : youwenfeng
     * @Date : 2018/7/27
     */
    public static <FROM, TO> TO dto2po(FROM dto, Class<TO> clazz) {
        return converte(dto, clazz);
    }

    /**
     * @param dtoList
     * @param clazz   PO.class
     * @return : java.util.List<T>
     * @Description : 批量 dto转po
     * @Author : youwenfeng
     * @Date : 2018/7/27
     */
    public static <FROM, TO> List<TO> dto2po(List<FROM> dtoList, Class<TO> clazz) {
        return converte(dtoList, clazz);
    }


    /**
     * @param from
     * @param clazz
     * @return : T
     * @Description : 单转换
     * @Author : youwenfeng
     * @Date : 2018/7/27
     */
    private static <FROM, TO> TO converte(FROM from, Class<TO> clazz) {
        TO to = null;
        if (null != from) {
            try {
                to = clazz.newInstance();
                ConvertUtils.register(new DateConverter(null), java.util.Date.class);
                ConvertUtils.register(new LongConverter(null), Long.class);
                ConvertUtils.register(new ShortConverter(null), Short.class);
                ConvertUtils.register(new IntegerConverter(null), Integer.class);
                ConvertUtils.register(new DoubleConverter(null), Double.class);
                ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);
                ConvertUtils.register(new BooleanConverter(null), Boolean.class);
                BeanUtils.copyProperties(from, to);
            } catch (IllegalAccessException e) {
                LOG.error("IllegalAccessException: ", e.getMessage());
            } catch (InstantiationException e) {
                LOG.error("InstantiationException: ", e.getMessage());
            }
        }
        return to;
    }

    /**
     * @param fromList
     * @param clazz
     * @return : java.util.List<T>
     * @Description : 批量转换
     * @Author : youwenfeng
     * @Date : 2018/7/27
     */
    private static <FROM, TO> List<TO> converte(List<FROM> fromList, Class<TO> clazz) {
        List<TO> toList = new ArrayList<>();
        if (null != fromList && !fromList.isEmpty()) {
            for (FROM from : fromList) {
                TO to = converte(from, clazz);
                if (null != to) {
                    toList.add(to);
                }
            }
        }
        return toList;
    }

    public static List<String> Long2String(List<Long> list) {
        if (null == list) {
            return null;
        }
        List<String> stringList = new ArrayList<>();
        if (!list.isEmpty()) {
            for (Long l : list) {
                stringList.add(String.valueOf(l));
            }
        }
        return stringList;
    }

    /**
     * 将poList集合数据转换为dtoList集合数据
     * 支持将数字字符串转换为Integer类型
     *
     * @param poList
     * @param dtoClass
     * @return
     */
    public static <T> List<T> poListToDtoList(List poList, Class<T> dtoClass) {
        List<T> dtoList = new ArrayList<>();
        poList.stream().forEach(item -> {
            Map<String, Object> map = BeanUtil.beanToMap(item);
            T dto = BeanUtil.mapToBean(map, dtoClass, false);
            dtoList.add(dto);
        });
        return dtoList;
    }

}
